package com.basker.pisces.core.meta.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.sql.JDBCType;
import java.sql.Types;

import com.basker.pisces.core.jdbc.JdbcTypeMapper;
import com.basker.pisces.core.meta.IDataField;
import com.basker.pisces.core.meta.bean.BeanDataField;
import com.basker.pisces.core.meta.bean.BeanMeta;

/**
 * 标记返回值为基本数据类型的字段或get方法，获取一个{@link BeanDataField}
 *
 * <p>
 * <li>get/set 方法需要成对出现，且后缀名称必须一致，即getXXX/setXXX；
 * <li>get方法如果返回值是Boolean，可以以is作为前缀，即isXXX/serXXX;
 * <li>get方法的返回值类型，必须与set方法的参数类型一致；
 * <li>方法的类型必须声明成装箱类型，不可以是简单类型；
 *
 * @author hangwen
 * @see BeanDataField
 * @see BeanMeta
 */

@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.FIELD, ElementType.METHOD})
public @interface DataField {

    /**
     * 标记字段在xml序列换时是否时CDATA字段
     * <p>
     * 需要xml序列化时，设置此属性，默认false
     *
     * @return
     * @see IDataField#isCDATA();
     */
    boolean cData() default false;

    /**
     * 数据字段映射数据表的字段名
     *
     * <p>
     * 需要数据库持久化时，设置此属性
     *
     * @return
     * @see IDataField#getDbFieldName()
     */
    String dbFieldName() default "";

    /**
     * 字段在详细描述,用于生成DDL语句中注释
     *
     * @return
     * @see IDataField#getDescription()
     */
    String description() default "";

    /**
     * 显示名称
     *
     * @return
     * @see IDataField#getDisplayName()
     */
    String displayName() default "";

    /**
     * 是否是索引字段,用于生成DDL语句
     *
     * @return
     * @see IDataField#isIndexField()
     */
    boolean indexField() default false;

    /**
     * 设置字段的JDBC数据类型
     *
     * <p>
     * 需要数据库持久化时，设置此属性；
     *
     * <p>
     * 如果不设置，系统会根据方法的返回值类型自动匹配一个数据类型 目前系统自动匹配的规则见：{@link JdbcTypeMapper}
     *
     * <p>
     * 如果不想使用自动匹配，就需要自行设置数据类型，比如：方法返回值是Date，但数据库是TIMESTAMP，就需要手动设置了。
     *
     * @return
     * @see IDataMember#javaSqlType()
     * @see Types
     */
    JDBCType jdbcType() default JDBCType.NULL;

    /**
     * 数据库字段的长度,用于生成DDL语句
     *
     * @return
     * @see {@link IDataField#getLength()}
     */
    int length() default -1;

    /**
     * 字段的名称,为空的话会按照POJO规范取方法的属性名
     *
     * @return
     * @see IDataField#getName()
     */
    String name() default "";

    /**
     * 标记数据字段是主键字段
     * <p>
     * 需要数据库持久化时，设置此属性,默认false
     *
     * @return
     * @see IDataField#isPkField()
     */
    boolean pkField() default false;

    /**
     * 数据库字段的精度,用于生成DDL语句
     *
     * @return
     * @see {@link IDataField#getScale()}
     */
    int scale() default -1;

    /**
     * 字段在数据表中的顺序
     *
     * @return
     */
    int sort() default 0;

    /**
     * 数据字段映射字段所属表名
     *
     * <p>
     * 需要数据库持久化时，设置此属性；如果表名与主表表名一致，可以不设置；如果字段属于一对一子表，必须设置
     *
     * @return
     * @see IDataField#getHostTableName()
     */
    String tableName() default "";
}
